home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
misc
/
amag
/
AM9410_2.lha
/
Haufenweise
/
Programme
/
PoolSupport.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-18
|
6KB
|
217 lines
#include "PoolSupport.h"
/*
* CreatePool13 ist das Gegenstück zu CreatePool von 3.0.
* Es kreiert einen Speicher-Pool, aus dem man
* anschließend beliebige Stücke holen kann.
*
* Flags sind die üblichen Angaben zum Speicher
* wie sie auch bei AllocMem üblich sind
*
* RegionSize ist die Kachelgröße. Immer dann
* wenn im Pool für eine Allozierung nicht mehr
* genügend Speicher vorhanden ist, wird eine
* neue Kachel alloziert.
*
* NewSize gibt die Größe an, ab der bei einer
* Allozierung grundsätzlich eine neue Kachel
* besorgt wird.
*/
void *CreatePool13(ULONG Flags,ULONG RegionSize, ULONG NewSize)
{
struct Pool *poo = 0L;
if (NewSize <= RegionSize)
{
if (poo = AllocMem(sizeof(struct Pool),MEMF_CLEAR))
{
poo->Flags = Flags;
poo->RegionSize = RegionSize;
poo->NewSize = NewSize;
NewList(&(poo->MHAnchor));
}
}
return poo;
}
void DeletePool13(APTR MyPool)
{
struct MemHeader *mh,*next;
struct Pool *p = (struct Pool *)MyPool;
if (MyPool != NULL)
{ if (!IsListEmpty(&(p->MHAnchor)))
{ mh = (struct MemHeader *)p->MHAnchor.lh_Head;
while ((APTR)mh != &(p->MHAnchor.lh_Tail))
{ next = (struct MemHeader *)mh->mh_Node.ln_Succ;
FreeMemHeader(mh); // dann freigeben
mh = next; // und auf den nächsten
// setzen
}
}
FreeMem(p,sizeof(struct Pool));
}
}
/*
* request(): Öffnet einen System-Requester. Aufruf
* wie EasyRequest und Printf() !
*
* Input: char *title: Fenstertiteltext
* char *gadgets: Gadgettexte durch | getrennt
* char *text: Requestertext, Zeilen durch
* \n getrennt
*
* Ergebnis: 1 = linkes Gadget, 0 = rechtes Gadget, 2 = ..
*/
#include <intuition/intuition.h>
#include <clib/intuition_protos.h>
#include <dos/dosextens.h>
#include <stdarg.h>
long request(char *title, char *gadgets, char *text, ...)
{
long rc = 0;
struct EasyStruct textreq = {
sizeof (struct EasyStruct), 0L,0L,0L,0L};
struct Process *process;
struct Window *win;
va_list ap;
va_start(ap, text);
/* für Printf-Argumente */
if (process = (struct Process *)FindTask(NULL))
{ if ((long)(win = process->pr_WindowPtr) != -1)
{
textreq.es_Title = (UBYTE *)title;
textreq.es_TextFormat = (UBYTE *)text;
textreq.es_GadgetFormat = (UBYTE *)gadgets;
rc = EasyRequestArgs(win, &textreq, NULL, ap);
}
}
va_end(ap);
return(rc);
}
/*
* AllocPooled13 ist die Funktion, die Speicher aus einem
* Pool alloziert. Sie verhält sich wie die
* zugehörige 3.0-Funktion. Leider ist bei
* der 3.0-Dokumentation nicht geklärt, was
* passieren soll, wenn ein Speicherblock
* alloziert werden soll, der größer als
* RegionSize ist.
*
* Diese Funktion alloziert dann einen
* entsprechend großen Block, damit die
* Allozierung stattfinden kann.
*/
static BOOL _AllocRegion(struct Pool *p,ULONG Size)
{
struct MemHeader *mh = 0;
int poolsize;
poolsize = MAX(p->RegionSize,Size+8);
while (!(mh = AllocMemHeader(poolsize,p->Flags)))
{ /*struct Task *t = FindTask(0L);
if (!request(t->tc_Node.ln_Name,"Retry|Cancel",
"Not enough memory free!\n"
"Free some and try again")) */
{ return FALSE; // kein Speicher da
}
}
AddHead(&(p->MHAnchor),(struct Node *)mh);
return TRUE;
}
APTR AllocPooled13(void *MyPool,ULONG Size)
{
register struct Pool *p = (struct Pool *)MyPool;
struct MemHeader *mh = 0;
APTR newmem = 0;
/* Liste noch leer oder großer Bereich gefordert? */
if ((IsListEmpty(&(p->MHAnchor))) ||
(Size > p->NewSize))
{
/* dann allozieren */
if (!_AllocRegion(p,Size))
{
/* ging schief */
return NULL;
}
}
mh = (struct MemHeader *)p->MHAnchor.lh_Head;
/* bis eine Kachel genügend Speicher enthält */
while ((APTR)mh != &(p->MHAnchor.lh_Tail))
{
if (newmem = AllocateVec(mh,Size))
{
//PutStr("{ return newmem; }\n");
return newmem;
}
else
{ mh = (struct MemHeader *)mh->mh_Node.ln_Succ; }
}
/* wenn man hier ankommt, dann war in den
Kacheln nicht genügend Speicher. Also eine
neue Allozieren und von vorn */
if (!_AllocRegion(p,Size))
{ return NULL; }
else /* Rekursiv geht es weiter */
{ return AllocPooled13(p,Size); }
}
/*
* FreePooled13 ist das Gegenstück zu AllocPooled13().
*
* WARNUNG: FreePooled13() ist nicht aufrufkompatibel
* zu FreePooled() von 3.0. Es fehlt der 3.
* Parameter, der die Länge enthält. Dieser
* ist nicht nötig, da für die Allozierung
* immer AllocateVec() benutzt wird. Wer
* will, kann natürlich einen 3. Dummy-
* Parameter einführen.
*/
void FreePooled13(void *MyPool, APTR memaddr)
{
register struct Pool *p = (struct Pool *)MyPool;
struct MemHeader *mh = 0;
mh = (struct MemHeader *)p->MHAnchor.lh_Head;
/* bis die richtige Kachel gefunden ist */
while ((APTR)mh != &(p->MHAnchor.lh_Tail))
{
if ((memaddr >= mh->mh_Lower) &&
(memaddr < mh->mh_Upper))
{ DeallocateVec(mh,memaddr);
break;
}
else
{ mh = (struct MemHeader *)mh->mh_Node.ln_Succ; }
}
}